package com.glink.manage.service.Impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.glink.common.contants.BaseCodeConstants;
import com.glink.common.util.BaseCommonUtils;
import com.glink.manage.common.BeanKit;
import com.glink.manage.common.PoiTools;
import com.glink.manage.domain.LogBean;
import com.glink.manage.dto.log.LogExportDTO;
import com.glink.manage.dto.log.LogPageDTO;
import com.glink.manage.dto.log.LogSaveDTO;
import com.glink.manage.mapper.LogMapper;
import com.glink.manage.service.CodeService;
import com.glink.manage.service.LogService;
import com.glink.manage.service.UserService;
import com.glink.manage.vo.log.LogExportVO;
import com.glink.manage.vo.log.LogVO;
import com.glink.manage.vo.user.UserBaseInfoVO;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : qiushaoshan
 * @create 2024/6/24 11:12
 */
@Service
@Slf4j
public class LogServiceImpl extends ServiceImpl<LogMapper, LogBean> implements LogService {

    @Autowired
    private CodeService codeService;
    
    @Autowired
    private UserService userService;
    
    /**
     * 分页查询日志信息
     * @param pageDTO 分页查询日志信息
     * @return 日志信息
     */
    @Override
    public IPage<LogVO> findLogPage(LogPageDTO pageDTO) {
        
        IPage<LogBean> iPage = new Page<>(pageDTO.getPage(), pageDTO.getSize());

        LambdaQueryChainWrapper<LogBean> lambdaQueryChainWrapper = findLogInfo(pageDTO.getType(), pageDTO.getContent(), pageDTO.getCreateUserId(), pageDTO.getCreateUserName(), pageDTO.getStartTime(), pageDTO.getEndTime());

        IPage<LogBean> logBeanIPage = lambdaQueryChainWrapper.page(iPage);
        
        IPage<LogVO> logVOIPage = new Page<>(logBeanIPage.getCurrent(), logBeanIPage.getSize(), logBeanIPage.getTotal());
        List<LogBean> records = logBeanIPage.getRecords();
        List<LogVO> logVOList = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(records)){
            records.forEach(logBean -> logVOList.add(beanToVO(logBean)));
        }
        logVOIPage.setRecords(logVOList);

        return logVOIPage;
    }

    private LambdaQueryChainWrapper<LogBean> findLogInfo(String type, String content, String createUserId, String createUserName, Date startTime, Date endTime){
        return this.lambdaQuery()
                .eq(StringUtils.isNotEmpty(type), LogBean::getType, type)
                .like(StringUtils.isNotEmpty(content), LogBean::getContent, content)
                .eq(StringUtils.isNotEmpty(createUserId), LogBean::getCreateUser, createUserId)
                .like(StringUtils.isNotEmpty(createUserName), LogBean::getCreateUserFullName, createUserName)
                .ge(Objects.nonNull(startTime), LogBean::getCreateTime, Objects.nonNull(startTime) ? DateUtil.beginOfDay(startTime) : startTime)
                .le(Objects.nonNull(endTime), LogBean::getCreateTime, Objects.nonNull(endTime) ?  DateUtil.endOfDay(endTime) : endTime)
                .orderByDesc(LogBean::getCreateTime)
                .orderByDesc( LogBean::getId);
    }
    
    /**
     * 导出日志信息
     *
     * @param exportDTO
     * @return
     */
    @Override
    public String exportLog(LogExportDTO exportDTO) throws Exception {

        LambdaQueryChainWrapper<LogBean> lambdaQueryChainWrapper = findLogInfo(exportDTO.getType(), exportDTO.getContent(), exportDTO.getCreateUserId(), exportDTO.getCreateUserName(), exportDTO.getStartTime(), exportDTO.getEndTime());
        List<LogBean> logBeanList = lambdaQueryChainWrapper.list();
        List<LogExportVO> logExportVOList = Lists.newArrayList();
        AtomicInteger num = new AtomicInteger(1);
        if(CollectionUtils.isNotEmpty(logBeanList)){
            logBeanList.forEach(logBean -> {
                LogExportVO logExportVO = new LogExportVO();
                logExportVO.setNumber(num.getAndIncrement());
                logExportVO.setContent(logBean.getContent());
                logExportVO.setCreateUserFullName(logBean.getCreateUserFullName());
                logExportVO.setCreateTime(BaseCommonUtils.DATE_FORMAT_SECOND_0.format(logBean.getCreateTime()));
                logExportVO.setTypeName(codeService.findNameByParentTypeAndKey(BaseCodeConstants.CodeType_01.KEY_LogType, logBean.getType()));
                logExportVO.setTypeName(StringUtils.isNotEmpty(logExportVO.getTypeName()) ? logExportVO.getTypeName() : logBean.getType());
                logExportVO.setIpAddress(logBean.getIpAddress());
                logExportVOList.add(logExportVO);
            });
        }
        XSSFWorkbook workbook = PoiTools.addDataAndMeterHeaderWithObject(logExportVOList, "系统日志");
        String ret = System.getProperty("user.dir") + "/" +  System.currentTimeMillis() + ".xlsx";
        PoiTools.write2Disk(workbook, ret);
        return ret;
    }

    /**
     * 保存日志记录
     *
     * @param userId 用户ID
     * @param saveDTO 保存的信息
     * @return 状态
     */
    @Override
    public Boolean addLogRecord(String userId, LogSaveDTO saveDTO) {
        String userFullName = "";
        UserBaseInfoVO userBaseInfoVO = userService.findById(userId);
        if(Objects.nonNull(userBaseInfoVO)){
            userFullName = userBaseInfoVO.getFullName();
        }
        
        LogBean logBean = new LogBean();
        logBean.setId(BaseCommonUtils.generateUUID());
        logBean.setType(saveDTO.getType());
        logBean.setContent(saveDTO.getContent());
        logBean.setCreateUserFullName(userFullName);
        logBean.setCreateUser(userId);
        logBean.setIpAddress(saveDTO.getIp());

        return this.save(logBean);
    }

    /**
     * 保存日志记录
     *
     * @param userId 用户ID
     * @param userFullName 用户名称
     * @param type 日志类型
     * @param content 日志内容
     * @return 状态
     */
    @Override
    public Boolean addLogRecord(String userId, String userFullName, String type, String content, String ipAddress) {

        LogBean logBean = new LogBean();
        logBean.setId(BaseCommonUtils.generateUUID());
        logBean.setType(type);
        logBean.setContent(content);
        logBean.setCreateUserFullName(userFullName);
        logBean.setCreateUser(userId);
        logBean.setIpAddress(ipAddress);

        return this.save(logBean);
    }


    private LogVO beanToVO(LogBean logBean){
        LogVO logVO = new LogVO();
        BeanKit.copyProperties(logBean, logVO);

        logVO.setTypeName(codeService.findNameByParentTypeAndKey(BaseCodeConstants.CodeType_01.KEY_LogType, logBean.getType()));
        
        return logVO;
    }
}
